<!DOCTYPE html>
<html>
<head>
<title>Polygon Drawing Tool</title>
<!-- Copyright 1998-2016 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<link href="../assets/css/goSamples.css" rel="stylesheet" type="text/css" />  <!-- you don't need to use this -->
<script src="goSamples.js"></script>  <!-- this is only for the GoJS Samples framework -->
<script src="PolygonDrawingTool.js"></script>
<script src="GeometryReshapingTool.js"></script>

<script id="code">
  function init() {
    if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv");

    myDiagram.toolManager.mouseDownTools.insertAt(3, new GeometryReshapingTool());

    myDiagram.nodeTemplate =
      $(go.Node,
        { locationSpot: go.Spot.Center },  // to support rotation about the center
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        { selectionAdorned: true, selectionObjectName: "SHAPE",
          selectionAdornmentTemplate:  // custom selection adornment: a blue rectangle
            $(go.Adornment, "Auto",
              $(go.Shape, { stroke: "dodgerblue", fill: null }),
              $(go.Placeholder, { margin: -1 }))
        },
        { resizable: true, resizeObjectName: "SHAPE" },
        { rotatable: true, rotateObjectName: "SHAPE" },
        { reshapable: true },  // GeometryReshapingTool assumes nonexistent Part.reshapeObjectName would be "SHAPE"
        $(go.Shape,
          { name: "SHAPE", fill: "lightgray", strokeWidth: 1.5 },
          new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
          new go.Binding("angle").makeTwoWay(),
          new go.Binding("geometryString", "geo").makeTwoWay(),
          new go.Binding("fill"),
          new go.Binding("stroke"),
          new go.Binding("strokeWidth")));

    // create polygon drawing tool for myDiagram, defined in PolygonDrawingTool.js
    var tool = new PolygonDrawingTool();
    // provide the default JavaScript object for a new polygon in the model
    tool.archetypePartData =
      { fill: "yellow", stroke: "blue", strokeWidth: 3 };
    tool.isPolygon = true;  // for a polyline drawing tool set this property to false
    // install as first mouse-down-tool
    myDiagram.toolManager.mouseDownTools.insertAt(0, tool);

    load();  // load a simple diagram from the textarea
  }

  function mode(draw, polygon) {
    // assume PolygonDrawingTool is the first tool in the mouse-down-tools list
    var tool = myDiagram.toolManager.mouseDownTools.elt(0);
    tool.isEnabled = draw;
    tool.isPolygon = polygon;
    tool.archetypePartData.fill = (polygon ? "yellow" : null);
    tool.temporaryShape.fill = (polygon ? "yellow" : null);
  }

  // this command ends the PolygonDrawingTool
  function finish(commit) {
    var tool = myDiagram.currentTool;
    if (commit && tool instanceof PolygonDrawingTool) {
      var lastInput = myDiagram.lastInput;
      if (lastInput.event instanceof window.MouseEvent) tool.removeLastPoint();  // remove point from last mouse-down
      tool.finishShape();
    } else {
      tool.doCancel();
    }
  }

  // this command removes the last clicked point from the temporary Shape
  function undo() {
    var tool = myDiagram.currentTool;
    if (tool instanceof PolygonDrawingTool) {
      var lastInput = myDiagram.lastInput;
      if (lastInput.event instanceof window.MouseEvent) tool.removeLastPoint();  // remove point from last mouse-down
      tool.undo();
    }
  }

  function updateAllAdornments() {  // called after checkboxes change Diagram.allow...
    myDiagram.selection.each(function(p) { p.updateAdornments(); });
  }

  // save a model to and load a model from Json text, displayed below the Diagram
  function save() {
    var str = '{ "position": "' + go.Point.stringify(myDiagram.position) + '",\n  "model": ' + myDiagram.model.toJson() + ' }';
    document.getElementById("mySavedDiagram").value = str;
  }
  function load() {
    var str = document.getElementById("mySavedDiagram").value;
    try {
      var json = JSON.parse(str);
      myDiagram.initialPosition = go.Point.parse(json.position || "0 0");
      myDiagram.model = go.Model.fromJson(json.model);
      myDiagram.model.undoManager.isEnabled = true;
    } catch (ex) {
      alert(ex);
    }
  }
</script>
</head>
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px gray; width: 100%; height: 350px"></div>
  <div id="buttons">
    <button onclick="mode(false)">Select</button>
    <button onclick="mode(true, true)">Draw Polygon</button>
    <button onclick="mode(true, false)">Draw Polyline</button>
    <button onclick="finish(true)">Finish Drawing</button>
    <button onclick="finish(false)">Cancel Drawing</button>
    <button onclick="undo()">Undo Last Point</button>
    <br/>
    <label><input type="checkbox" onclick="myDiagram.allowResize = !myDiagram.allowResize; updateAllAdornments()" checked="checked" />Allow Resizing</label>
    <label><input type="checkbox" onclick="myDiagram.allowReshape = !myDiagram.allowReshape; updateAllAdornments()" checked="checked" />Allow Reshaping</label>
    <label><input type="checkbox" onclick="myDiagram.allowRotate = !myDiagram.allowRotate; updateAllAdornments()" checked="checked" />Allow Rotating</label>
  </div>
  <p>
    This sample demonstrates the PolygonDrawingTool, a custom <a>Tool</a> added to the Diagram's mouseDownTools.
    It is defined in its own file, as <a href="PolygonDrawingTool.js">PolygonDrawingTool.js</a>.
    It also demonstrates the GeometryReshapingTool, another custom tool,
    defined in <a href="GeometryReshapingTool.js">GeometryReshapingTool.js</a>.
  </p>
  <p>
    These extensions serve as examples of features that can be added to GoJS by writing new classes.
    With the PolygonDrawingTool, a new mode is supported that allows the user to draw custom shapes.
    With the GeometryReshapingTool, users can change the geometry (i.e. the "shape") of a <a>Shape</a>s in a selected <a>Node</a>.
  <br/>
    Click a "Draw" button and then click in the diagram to place a new point in a polygon or polyline shape.
    Right-click, double-click, or Enter to finish.  Press <b>Escape</b> to cancel, or <b>Z</b> to remove the last point.
    Click the "Select" button to switch back to the normal selection behavior, so that you can select, resize, and rotate the shapes.
    The checkboxes control whether you can resize, reshape, and/or rotate selected shapes.
  </p>
  <div>
    <button onclick="save()">Save</button>
    <button onclick="load()">Load</button>
  </div>
  <textarea id="mySavedDiagram" style="width:100%;height:300px">
{ "position": "0 0",
  "model": { "class": "go.GraphLinksModel",
  "nodeDataArray": [ {"loc":"183 148", "geo":"F M0 145 L75 2 L131 87 L195 0 L249 143z", "key":-1} ],
  "linkDataArray": [  ]
} }
  </textarea>
</div>
</body>
</html>
